%{
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#include "config.h"

using namespace std;
struct clause {
	union {
		char attrib[ATTRIB_NAME_LENGTH];
		int  numattrib;
	}u;
	char op[4];
	int  val;
};

#include "index.hh"
#include "stg_mgr.hh"
#include "block.hh"
#include "buf_mgr.hh"
#include "table.hh"
#include "db.hh"

#define yywrap()	0

class catalog *db1;

FlexLexer* lexer;
char tokens[MAX_TOKENS][MAX_TOKEN_SIZE];
int token_num = 0;
int status = 0;
int num_blocks = 0;

double	command_time = 0;
clock_t start, finish;
int	timer=0;
struct timeval t_start, t_finish;
struct timezone tz1;

#include "query_processor.hh"

int main(int argc, char *argv[])
{
	START;
	getversion();
	++argv, --argc;  /* Skip over program name. */

	lexer = new yyFlexLexer;

	if (argc > 0)
		
		num_blocks = atoi(argv[0]);
	else
		num_blocks = 4;
	
	db1 = new catalog(CATALOG_FILE, num_blocks);
	END;

	while(lexer->yylex() != 0);

	return 0;
}



//select[ ][*][ ]from[ ][*]				extract_tokens(lexer->YYtext()); select_call();
//select[ ]{ATTRIB_NAMES}[ ]from[ ][*]			extract_tokens(); select_call();
%}

DIGIT	[0-9]
ALPHA	[a-zA-Z]
ALPHANUM	[a-zA-Z0-9]

NAME		{ALPHA}{ALPHANUM}{0,16}
TABLE_NAME	{ALPHA}{ALPHANUM}{0,7}
ATTRIB_NAME	{ALPHA}{ALPHANUM}{0,2}
NUMBER		{DIGIT}{0,31}

TABLE_NAME2	[,]{ALPHA}{ALPHANUM}{0,2}
ATTRIB_NAME2	[,]{ALPHA}{ALPHANUM}{0,2}
NUMBER2		[,]{DIGIT}{0,31}

TABLE_NAMES	{TABLE_NAME}{TABLE_NAME2}{0,100}
ATTRIB_NAMES	{ATTRIB_NAME}{ATTRIB_NAME2}{0,7}
NUMBERS		{NUMBER}{NUMBER2}{0,7}

NODUPS		[[]NO[ ]DUPLICATES[]]

%%

CREATE[ ]TABLE[ ]{TABLE_NAME}[(]{ATTRIB_NAMES}[)];[\n]		{ START; create_table(); END; }
INSERT[ ]INTO[ ]{TABLE_NAME}[ ]VALUES[(]{NUMBERS}[)];[\n]	{ START; insert_values(); END; }

SELECT[ ][*][ ]FROM[ ]{TABLE_NAME};[\n] 				{ START; select_call(); END; }
SELECT[ ]{ATTRIB_NAMES}[ ]FROM[ ]{TABLE_NAME};[\n]			{ START; select_call(); END; }
SELECT[ ][*][ ]FROM[ ]{TABLE_NAME}[ ]WHERE[ ]{ATTRIB_NAME}[=]{NUMBER};[\n]		{ START; select_call(); END; }
SELECT[ ]{ATTRIB_NAMES}[ ]FROM[ ]{TABLE_NAME}[ ]WHERE[ ]{ATTRIB_NAME}[=]{NUMBER};[\n]	{ START; select_call(); END; }

PRINT[ ]TABLE[ ]{TABLE_NAME};[\n]	{ START; print_table();   END; }
PRINT[ ]CATALOG;[\n]			{ START; print_catalog(); END; }

PRINT[ ]HIT[ ]RATE;[\n]			{ START; print_hit_rate(); END;	}
PRINT[ ]BUFFER[ ]{DIGIT};[\n]		{ START; print_buffer();  END;	}
PRINT[ ]BUFFER;[\n]			{ START; print_buffers(); END;	}

SET[ ]TIMER[ ]ON;[\n]			{ START; timer=1; PRINT("Timer is now ON \n"); END; }
SET[ ]TIMER[ ]OFF;[\n]			{ START; timer=0; PRINT("Timer is now OFF\n"); END; }

PRINT[ ]INDEX[ ]{NAME};[\n]		{ START; print_index(); END;	}
SET[ ]INDEX[ ]DEBUG[ ]ON;[\n]		{ START; iDebugON=1;PRINT("INDEX DEBUG Mode is now ON\n");  END;	}
SET[ ]INDEX[ ]DEBUG[ ]OFF;[\n]		{ START; iDebugON=0;PRINT("INDEX DEBUG Mode is now OFF\n"); END;	}

CREATE[ ]INDEX[ ]{NAME}[ ]ON[ ]{TABLE_NAME}[(]{ATTRIB_NAME}[)];[\n] 		{ START; create_index(1); END;	}
CREATE[ ]INDEX[ ]{NAME}[ ]ON[ ]{TABLE_NAME}[(]{ATTRIB_NAME}[)][ ]{NODUPS};[\n]	{ START; create_index(0); END;	}

COMMIT[;][\n]				{ START; commit(); 	END; }
QUIT[;][\n]				{ quit(); exit(status);	     } 

[\n]					{ START; PRINT("Invalid Query\n"); END; }
.					//printf("Invalid Query\n");
%%

